package com.libleveldb.util

import java.util.Comparator
import kotlin.experimental.and
import kotlin.math.min

object Bytes {
    /**
     * Utility [java.util.Comparator] for lexicographic comparisons of byte arrays.
     *
     * @see .lexicographicCompare
     */
    @JvmField
    val COMPARATOR: Comparator<ByteArray> = Comparator { a, b -> lexicographicCompare(a, b) }

    /**
     * Lexicographically compares two byte arrays, the way the default comparator in a
     * [com.libleveldb.implementation.NativeLevelDB] instance works.
     *
     * @param a nullable byte array
     * @param b nullable byte array
     * @return greater than 0 if a > b, less than 0 if a < b, or 0 if a = b
     */
    private fun lexicographicCompare(a: ByteArray?, b: ByteArray?): Int {
        if (a.contentEquals(b)) {
            return 0
        }
        if (a == null) {
            return -1
        }
        if (b == null) {
            return 1
        }
        val maxLength = min(a.size, b.size)
        for (i in 0 until maxLength) {
            if (a[i] and 0xFF.toByte() == b[i] and 0xFF.toByte()) {
                continue
            }
            return if (a[i] and 0xFF.toByte() > b[i] and 0xFF.toByte()) {
                i + 1
            } else -(i + 1)
        }
        if (a.size > maxLength) {
            for (i in b.size until a.size) {
                if (a[i] != 0.toByte()) {
                    return i + 1
                }
            }
        }
        for (i in a.size until b.size) {
            if (b[i] != 0.toByte()) {
                return -(i + 1)
            }
        }
        return 0
    }
}